/*
 * Copyright (c) 2009, Michael van der Westhuizen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *    - Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    - Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following
 *      disclaimer in the documentation and/or other materials provided
 *      with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include "imq.h"

#include "mqstatus.c"
#include "util.c"
#include "mqdestination.c"
#include "mqmessage.c"
#include "mqproducer.c"
#include "mqconsumer-callbacks.c"
#include "mqconsumer.c"
#include "mqsession.c"
#include "mqconnection-callbacks.c"
#include "mqconnection.c"
#include "ssl.c"


static PyMethodDef mqcrt_methods[] = {
    {"MQInitializeSSL", (PyCFunction)mqcrt_MQInitializeSSL, METH_VARARGS | METH_KEYWORDS, "Initialise the SSL library. Must be called before connecting to the broker over SSL."},
    {NULL}
};


#ifndef PyMODINIT_FUNC
#define PyMODINIT_FUNC void
#endif

PyMODINIT_FUNC
initimq(void)
{
    PyObject* m;

#ifdef WITH_THREAD
    PyEval_InitThreads();
#endif

#ifdef XA_DEVELOPMENT
    mqcrt_MQXAConnectionType.tp_new = PyType_GenericNew;
#endif

    /* we do not want a tp_new for MQStatus - the user can't create objects of this type. */
    if (PyType_Ready(&mqcrt_MQStatusType) < 0)
        return;

    if (PyType_Ready(&mqcrt_MQConnectionType) < 0)
        return;

#ifdef XA_DEVELOPMENT
    if (PyType_Ready(&mqcrt_MQXAConnectionType) < 0)
        return;
#endif

    if (PyType_Ready(&mqcrt_MQDestinationType) < 0)
        return;

    if (PyType_Ready(&mqcrt_MQProducerType) < 0)
        return;

    if (PyType_Ready(&mqcrt_MQConsumerType) < 0)
        return;

    if (PyType_Ready(&mqcrt_MQSessionType) < 0)
        return;

    if (PyType_Ready(&mqcrt_MQMessageType) < 0)
        return;

    m = Py_InitModule3("imq", mqcrt_methods,
        "Wrapper for the Sun GlassFish(tm) Message Queue C runtime library.");

    Py_XINCREF(&mqcrt_MQStatusType);
    PyModule_AddObject(m, "MQStatus", (PyObject *)&mqcrt_MQStatusType);
    Py_XINCREF(&mqcrt_MQConnectionType);
    PyModule_AddObject(m, "MQConnection", (PyObject *)&mqcrt_MQConnectionType);
#ifdef XA_DEVELOPMENT
    Py_XINCREF(&mqcrt_MQXAConnectionType);
    PyModule_AddObject(m, "MQXAConnection", (PyObject *)&mqcrt_MQXAConnectionType);
#endif
    Py_XINCREF(&mqcrt_MQDestinationType);
    PyModule_AddObject(m, "MQDestination", (PyObject *)&mqcrt_MQDestinationType);
    Py_XINCREF(&mqcrt_MQProducerType);
    PyModule_AddObject(m, "MQProducer", (PyObject *)&mqcrt_MQProducerType);
    Py_XINCREF(&mqcrt_MQConsumerType);
    PyModule_AddObject(m, "MQConsumer", (PyObject *)&mqcrt_MQConsumerType);
    Py_XINCREF(&mqcrt_MQSessionType);
    PyModule_AddObject(m, "MQSession", (PyObject *)&mqcrt_MQSessionType);
    Py_XINCREF(&mqcrt_MQMessageType);
    PyModule_AddObject(m, "MQMessage", (PyObject *)&mqcrt_MQMessageType);

    MQStatusError = PyErr_NewException("imq.MQStatusError", NULL, NULL);
    Py_XINCREF(MQStatusError);

    if (PyModule_AddObject(m, "MQStatusError", MQStatusError) < 0) {
        return;
    }

    /*
     * Constants: mqbasictypes.h
     */

    PyModule_AddIntConstant(m, "MQ_PLATFORM_UNKNOWN", MQ_PLATFORM_UNKNOWN);
    PyModule_AddIntConstant(m, "MQ_PLATFORM_SOLARIS", MQ_PLATFORM_SOLARIS);
    PyModule_AddIntConstant(m, "MQ_PLATFORM_LINUX", MQ_PLATFORM_LINUX);
    PyModule_AddIntConstant(m, "MQ_PLATFORM_HPUX", MQ_PLATFORM_HPUX);
    PyModule_AddIntConstant(m, "MQ_PLATFORM_AIX", MQ_PLATFORM_AIX);
    PyModule_AddIntConstant(m, "MQ_PLATFORM_WIN32", MQ_PLATFORM_WIN32);
    PyModule_AddIntConstant(m, "MQ_PLATFORM_DARWIN", MQ_PLATFORM_DARWIN);
#if defined(SOLARIS)
    PyModule_AddIntConstant(m, "MQ_PLATFORM", MQ_PLATFORM_SOLARIS);
    PyModule_AddStringConstant(m, "MQ_PLATFORM_NAME", "SOLARIS");
#elif defined(LINUX)
    PyModule_AddIntConstant(m, "MQ_PLATFORM", MQ_PLATFORM_LINUX);
    PyModule_AddStringConstant(m, "MQ_PLATFORM_NAME", "LINUX");
#elif defined(HPUX)
    PyModule_AddIntConstant(m, "MQ_PLATFORM", MQ_PLATFORM_HPUX);
    PyModule_AddStringConstant(m, "MQ_PLATFORM_NAME", "HPUX");
#elif defined(AIX)
    PyModule_AddIntConstant(m, "MQ_PLATFORM", MQ_PLATFORM_AIX);
    PyModule_AddStringConstant(m, "MQ_PLATFORM_NAME", "AIX");
#elif defined(WIN32)
    PyModule_AddIntConstant(m, "MQ_PLATFORM", MQ_PLATFORM_WIN32);
    PyModule_AddStringConstant(m, "MQ_PLATFORM_NAME", "WIN32");
#elif defined(DARWIN)
    PyModule_AddIntConstant(m, "MQ_PLATFORM", MQ_PLATFORM_DARWIN);
    PyModule_AddStringConstant(m, "MQ_PLATFORM_NAME", "DARWIN");
#else
    PyModule_AddIntConstant(m, "MQ_PLATFORM", MQ_PLATFORM_UNKNOWN);
    PyModule_AddStringConstant(m, "MQ_PLATFORM_NAME", "UNKNOWN");
#endif

    /*
     * Constants: mqtypes.h
     */
    /* MQType */
    PyModule_AddIntConstant(m, "MQ_BOOL_TYPE", MQ_BOOL_TYPE);
    PyModule_AddIntConstant(m, "MQ_INT8_TYPE", MQ_INT8_TYPE);
    PyModule_AddIntConstant(m, "MQ_INT16_TYPE", MQ_INT16_TYPE);
    PyModule_AddIntConstant(m, "MQ_INT32_TYPE", MQ_INT32_TYPE);
    PyModule_AddIntConstant(m, "MQ_INT64_TYPE", MQ_INT64_TYPE);
    PyModule_AddIntConstant(m, "MQ_FLOAT32_TYPE", MQ_FLOAT32_TYPE);
    PyModule_AddIntConstant(m, "MQ_FLOAT64_TYPE", MQ_FLOAT64_TYPE);
    PyModule_AddIntConstant(m, "MQ_STRING_TYPE", MQ_STRING_TYPE);
    PyModule_AddIntConstant(m, "MQ_INVALID_TYPE", MQ_INVALID_TYPE);

    /* MQMessageType */
    PyModule_AddIntConstant(m, "MQ_TEXT_MESSAGE", MQ_TEXT_MESSAGE);
    PyModule_AddIntConstant(m, "MQ_BYTES_MESSAGE", MQ_BYTES_MESSAGE);
    PyModule_AddIntConstant(m, "MQ_MESSAGE", MQ_MESSAGE);
    PyModule_AddIntConstant(m, "MQ_UNSUPPORTED_MESSAGE", MQ_UNSUPPORTED_MESSAGE);

    /* MQAckMode */
    PyModule_AddIntConstant(m, "MQ_AUTO_ACKNOWLEDGE", MQ_AUTO_ACKNOWLEDGE);
    PyModule_AddIntConstant(m, "MQ_CLIENT_ACKNOWLEDGE", MQ_CLIENT_ACKNOWLEDGE);
    PyModule_AddIntConstant(m, "MQ_DUPS_OK_ACKNOWLEDGE", MQ_DUPS_OK_ACKNOWLEDGE);
    PyModule_AddIntConstant(m, "MQ_SESSION_TRANSACTED", MQ_SESSION_TRANSACTED);

    /* MQDeliveryMode */
    PyModule_AddIntConstant(m, "MQ_NON_PERSISTENT_DELIVERY", MQ_NON_PERSISTENT_DELIVERY);
    PyModule_AddIntConstant(m, "MQ_PERSISTENT_DELIVERY", MQ_PERSISTENT_DELIVERY);

    /* MQDestinationType */
    PyModule_AddIntConstant(m, "MQ_QUEUE_DESTINATION", MQ_QUEUE_DESTINATION);
    PyModule_AddIntConstant(m, "MQ_TOPIC_DESTINATION", MQ_TOPIC_DESTINATION);

    /* MQReceiveMode */
    PyModule_AddIntConstant(m, "MQ_SESSION_SYNC_RECEIVE", MQ_SESSION_SYNC_RECEIVE);
    PyModule_AddIntConstant(m, "MQ_SESSION_ASYNC_RECEIVE", MQ_SESSION_ASYNC_RECEIVE);

    /*
     * Constants: mqheader-props.h
     */
    PyModule_AddStringConstant(m, "MQ_PERSISTENT_HEADER_PROPERTY", MQ_PERSISTENT_HEADER_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_REDELIVERED_HEADER_PROPERTY", MQ_REDELIVERED_HEADER_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_EXPIRATION_HEADER_PROPERTY", MQ_EXPIRATION_HEADER_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_PRIORITY_HEADER_PROPERTY", MQ_PRIORITY_HEADER_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_TIMESTAMP_HEADER_PROPERTY", MQ_TIMESTAMP_HEADER_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_MESSAGE_ID_HEADER_PROPERTY", MQ_MESSAGE_ID_HEADER_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_CORRELATION_ID_HEADER_PROPERTY", MQ_CORRELATION_ID_HEADER_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_MESSAGE_TYPE_HEADER_PROPERTY", MQ_MESSAGE_TYPE_HEADER_PROPERTY);

    /*
     * Constants: mqconnection-props.h
     */
    PyModule_AddStringConstant(m, "MQ_BROKER_HOST_PROPERTY", MQ_BROKER_HOST_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_BROKER_PORT_PROPERTY", MQ_BROKER_PORT_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_SERVICE_PORT_PROPERTY", MQ_SERVICE_PORT_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_CONNECTION_TYPE_PROPERTY", MQ_CONNECTION_TYPE_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_ACK_TIMEOUT_PROPERTY", MQ_ACK_TIMEOUT_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_ACK_ON_PRODUCE_PROPERTY", MQ_ACK_ON_PRODUCE_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_ACK_ON_ACKNOWLEDGE_PROPERTY", MQ_ACK_ON_ACKNOWLEDGE_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_CONNECTION_FLOW_COUNT_PROPERTY", MQ_CONNECTION_FLOW_COUNT_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_CONNECTION_FLOW_LIMIT_ENABLED_PROPERTY", MQ_CONNECTION_FLOW_LIMIT_ENABLED_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_CONNECTION_FLOW_LIMIT_PROPERTY", MQ_CONNECTION_FLOW_LIMIT_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_PING_INTERVAL_PROPERTY", MQ_PING_INTERVAL_PROPERTY);

    /* SSL **/
    PyModule_AddStringConstant(m, "MQ_SSL_BROKER_IS_TRUSTED", MQ_SSL_BROKER_IS_TRUSTED);
    PyModule_AddStringConstant(m, "MQ_SSL_CHECK_BROKER_FINGERPRINT", MQ_SSL_CHECK_BROKER_FINGERPRINT);
    PyModule_AddStringConstant(m, "MQ_SSL_BROKER_CERT_FINGERPRINT", MQ_SSL_BROKER_CERT_FINGERPRINT);

    /* metadata properties to be used with MQGetMetaData */
    PyModule_AddStringConstant(m, "MQ_NAME_PROPERTY", MQ_NAME_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_VERSION_PROPERTY", MQ_VERSION_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_MAJOR_VERSION_PROPERTY", MQ_MAJOR_VERSION_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_MINOR_VERSION_PROPERTY", MQ_MINOR_VERSION_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_MICRO_VERSION_PROPERTY", MQ_MICRO_VERSION_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_SERVICE_PACK_PROPERTY", MQ_SERVICE_PACK_PROPERTY);
    PyModule_AddStringConstant(m, "MQ_UPDATE_RELEASE_PROPERTY", MQ_UPDATE_RELEASE_PROPERTY);

    /*
     * Constants: mqversion.h
     */
    PyModule_AddStringConstant(m, "MQ_NAME", MQ_NAME);
    PyModule_AddStringConstant(m, "MQ_VERSION", MQ_VERSION);
    PyModule_AddIntConstant(m, "MQ_VMAJOR", MQ_VMAJOR);
    PyModule_AddIntConstant(m, "MQ_VMINOR", MQ_VMINOR);
    PyModule_AddIntConstant(m, "MQ_VMICRO", MQ_VMICRO);
    PyModule_AddIntConstant(m, "MQ_SVCPACK", MQ_SVCPACK);
    PyModule_AddIntConstant(m, "MQ_URELEASE", MQ_URELEASE);

    /*
     * Constants: mqerrors.h
     */
    PyModule_AddIntConstant(m, "MQ_SUCCESS", MQ_SUCCESS);
    PyModule_AddIntConstant(m, "MQ_OK", MQ_OK);
    PyModule_AddIntConstant(m, "MQ_BASE_ERROR_CODE", MQ_BASE_ERROR_CODE);
    PyModule_AddIntConstant(m, "MQ_INTERNAL_ERROR", MQ_INTERNAL_ERROR);
    PyModule_AddIntConstant(m, "MQ_NULL_PTR_ARG", MQ_NULL_PTR_ARG);
    PyModule_AddIntConstant(m, "MQ_WRONG_ARG_BUFFER_SIZE", MQ_WRONG_ARG_BUFFER_SIZE);
    PyModule_AddIntConstant(m, "MQ_OUT_OF_MEMORY", MQ_OUT_OF_MEMORY);
    PyModule_AddIntConstant(m, "MQ_FILE_OUTPUT_ERROR", MQ_FILE_OUTPUT_ERROR);
    PyModule_AddIntConstant(m, "MQ_NOT_FOUND", MQ_NOT_FOUND);
    PyModule_AddIntConstant(m, "MQ_BAD_VECTOR_INDEX", MQ_BAD_VECTOR_INDEX);

    PyModule_AddIntConstant(m, "MQ_VECTOR_TOO_BIG", MQ_VECTOR_TOO_BIG);
    PyModule_AddIntConstant(m, "MQ_UNEXPECTED_NULL", MQ_UNEXPECTED_NULL);
    PyModule_AddIntConstant(m, "MQ_INVALID_ITERATOR", MQ_INVALID_ITERATOR);
    PyModule_AddIntConstant(m, "MQ_STRING_NOT_NUMBER", MQ_STRING_NOT_NUMBER);
    PyModule_AddIntConstant(m, "MQ_NUMBER_NOT_UINT16", MQ_NUMBER_NOT_UINT16);
    PyModule_AddIntConstant(m, "MQ_OBJECT_NOT_CLONEABLE", MQ_OBJECT_NOT_CLONEABLE);
    PyModule_AddIntConstant(m, "MQ_HASH_VALUE_ALREADY_EXISTS", MQ_HASH_VALUE_ALREADY_EXISTS);
    PyModule_AddIntConstant(m, "MQ_HASH_TABLE_ALLOCATION_FAILED", MQ_HASH_TABLE_ALLOCATION_FAILED);
    PyModule_AddIntConstant(m, "MQ_INCOMPATIBLE_LIBRARY", MQ_INCOMPATIBLE_LIBRARY);
    PyModule_AddIntConstant(m, "MQ_CONCURRENT_ACCESS", MQ_CONCURRENT_ACCESS);
    PyModule_AddIntConstant(m, "MQ_CONCURRENT_DEADLOCK", MQ_CONCURRENT_DEADLOCK);
    PyModule_AddIntConstant(m, "MQ_CONCURRENT_NOT_OWNER", MQ_CONCURRENT_NOT_OWNER);

    PyModule_AddIntConstant(m, "MQ_NOT_IPV4_ADDRESS", MQ_NOT_IPV4_ADDRESS);

    PyModule_AddIntConstant(m, "MQ_UNINITIALIZED_STREAM", MQ_UNINITIALIZED_STREAM);
    PyModule_AddIntConstant(m, "MQ_END_OF_STREAM", MQ_END_OF_STREAM);
    PyModule_AddIntConstant(m, "MQ_INPUT_STREAM_ERROR", MQ_INPUT_STREAM_ERROR);

    PyModule_AddIntConstant(m, "MQ_SERIALIZE_NOT_CLASS_DEF", MQ_SERIALIZE_NOT_CLASS_DEF);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_BAD_CLASS_UID", MQ_SERIALIZE_BAD_CLASS_UID);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_BAD_MAGIC_NUMBER", MQ_SERIALIZE_BAD_MAGIC_NUMBER);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_BAD_VERSION", MQ_SERIALIZE_BAD_VERSION);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_NOT_HASHTABLE", MQ_SERIALIZE_NOT_HASHTABLE);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_UNEXPECTED_BYTES", MQ_SERIALIZE_UNEXPECTED_BYTES);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_UNRECOGNIZED_CLASS", MQ_SERIALIZE_UNRECOGNIZED_CLASS);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_BAD_SUPER_CLASS", MQ_SERIALIZE_BAD_SUPER_CLASS);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_BAD_HANDLE", MQ_SERIALIZE_BAD_HANDLE);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_NOT_CLASS_HANDLE", MQ_SERIALIZE_NOT_CLASS_HANDLE);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_NOT_OBJECT_HANDLE", MQ_SERIALIZE_NOT_OBJECT_HANDLE);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_STRING_TOO_BIG", MQ_SERIALIZE_STRING_TOO_BIG);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_CANNOT_CLONE", MQ_SERIALIZE_CANNOT_CLONE);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_NO_CLASS_DESC", MQ_SERIALIZE_NO_CLASS_DESC);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_CORRUPTED_HASHTABLE", MQ_SERIALIZE_CORRUPTED_HASHTABLE);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_TEST_ERROR", MQ_SERIALIZE_TEST_ERROR);
    PyModule_AddIntConstant(m, "MQ_SERIALIZE_STRING_CONTAINS_NULL", MQ_SERIALIZE_STRING_CONTAINS_NULL);

    PyModule_AddIntConstant(m, "MQ_PROPERTY_NULL", MQ_PROPERTY_NULL);
    PyModule_AddIntConstant(m, "MQ_PROPERTY_WRONG_VALUE_TYPE", MQ_PROPERTY_WRONG_VALUE_TYPE);
    PyModule_AddIntConstant(m, "MQ_INVALID_TYPE_CONVERSION", MQ_INVALID_TYPE_CONVERSION);
    PyModule_AddIntConstant(m, "MQ_NULL_STRING", MQ_NULL_STRING);
    PyModule_AddIntConstant(m, "MQ_TYPE_CONVERSION_OUT_OF_BOUNDS", MQ_TYPE_CONVERSION_OUT_OF_BOUNDS);
    PyModule_AddIntConstant(m, "MQ_PROPERTY_FILE_ERROR", MQ_PROPERTY_FILE_ERROR);
    PyModule_AddIntConstant(m, "MQ_FILE_NOT_FOUND", MQ_FILE_NOT_FOUND);
    PyModule_AddIntConstant(m, "MQ_BASIC_TYPE_SIZE_MISMATCH", MQ_BASIC_TYPE_SIZE_MISMATCH);

    PyModule_AddIntConstant(m, "MQ_TCP_INVALID_PORT", MQ_TCP_INVALID_PORT);
    PyModule_AddIntConstant(m, "MQ_TCP_CONNECTION_CLOSED", MQ_TCP_CONNECTION_CLOSED);
    PyModule_AddIntConstant(m, "MQ_TCP_ALREADY_CONNECTED", MQ_TCP_ALREADY_CONNECTED);

    PyModule_AddIntConstant(m, "MQ_PORTMAPPER_INVALID_INPUT", MQ_PORTMAPPER_INVALID_INPUT);
    PyModule_AddIntConstant(m, "MQ_PORTMAPPER_WRONG_VERSION", MQ_PORTMAPPER_WRONG_VERSION);
    PyModule_AddIntConstant(m, "MQ_PORTMAPPER_ERROR", MQ_PORTMAPPER_ERROR);

    PyModule_AddIntConstant(m, "MQ_INVALID_PACKET", MQ_INVALID_PACKET);
    PyModule_AddIntConstant(m, "MQ_INVALID_PACKET_FIELD", MQ_INVALID_PACKET_FIELD);
    PyModule_AddIntConstant(m, "MQ_PACKET_OUTPUT_ERROR", MQ_PACKET_OUTPUT_ERROR);
    PyModule_AddIntConstant(m, "MQ_UNRECOGNIZED_PACKET_TYPE", MQ_UNRECOGNIZED_PACKET_TYPE);
    PyModule_AddIntConstant(m, "MQ_UNSUPPORTED_MESSAGE_TYPE", MQ_UNSUPPORTED_MESSAGE_TYPE);
    PyModule_AddIntConstant(m, "MQ_BAD_PACKET_MAGIC_NUMBER", MQ_BAD_PACKET_MAGIC_NUMBER);
    PyModule_AddIntConstant(m, "MQ_UNSUPPORTED_PACKET_VERSION", MQ_UNSUPPORTED_PACKET_VERSION);

    PyModule_AddIntConstant(m, "MQ_COULD_NOT_CONNECT_TO_BROKER", MQ_COULD_NOT_CONNECT_TO_BROKER);
    PyModule_AddIntConstant(m, "MQ_BROKER_CONNECTION_CLOSED", MQ_BROKER_CONNECTION_CLOSED);
    PyModule_AddIntConstant(m, "MQ_UNEXPECTED_ACKNOWLEDGEMENT", MQ_UNEXPECTED_ACKNOWLEDGEMENT);
    PyModule_AddIntConstant(m, "MQ_ACK_STATUS_NOT_OK", MQ_ACK_STATUS_NOT_OK);
    PyModule_AddIntConstant(m, "MQ_COULD_NOT_CREATE_THREAD", MQ_COULD_NOT_CREATE_THREAD);
    PyModule_AddIntConstant(m, "MQ_INVALID_AUTHENTICATE_REQUEST", MQ_INVALID_AUTHENTICATE_REQUEST);
    PyModule_AddIntConstant(m, "MQ_ADMIN_KEY_AUTH_MISMATCH", MQ_ADMIN_KEY_AUTH_MISMATCH);
    PyModule_AddIntConstant(m, "MQ_NO_AUTHENTICATION_HANDLER", MQ_NO_AUTHENTICATION_HANDLER);
    PyModule_AddIntConstant(m, "MQ_UNSUPPORTED_AUTH_TYPE", MQ_UNSUPPORTED_AUTH_TYPE);
    PyModule_AddIntConstant(m, "MQ_INVALID_CLIENTID", MQ_INVALID_CLIENTID);
    PyModule_AddIntConstant(m, "MQ_CLIENTID_IN_USE", MQ_CLIENTID_IN_USE);

    PyModule_AddIntConstant(m, "MQ_REUSED_CONSUMER_ID", MQ_REUSED_CONSUMER_ID);
    PyModule_AddIntConstant(m, "MQ_INVALID_CONSUMER_ID", MQ_INVALID_CONSUMER_ID);

    PyModule_AddIntConstant(m, "MQ_SOCKET_ERROR", MQ_SOCKET_ERROR);
    PyModule_AddIntConstant(m, "MQ_NEGATIVE_AMOUNT", MQ_NEGATIVE_AMOUNT);
    PyModule_AddIntConstant(m, "MQ_POLL_ERROR", MQ_POLL_ERROR);
    PyModule_AddIntConstant(m, "MQ_TIMEOUT_EXPIRED", MQ_TIMEOUT_EXPIRED);
    PyModule_AddIntConstant(m, "MQ_INVALID_PORT", MQ_INVALID_PORT);
    PyModule_AddIntConstant(m, "MQ_SOCKET_CONNECT_FAILED", MQ_SOCKET_CONNECT_FAILED);
    PyModule_AddIntConstant(m, "MQ_SOCKET_READ_FAILED", MQ_SOCKET_READ_FAILED);
    PyModule_AddIntConstant(m, "MQ_SOCKET_WRITE_FAILED", MQ_SOCKET_WRITE_FAILED);
    PyModule_AddIntConstant(m, "MQ_SOCKET_SHUTDOWN_FAILED", MQ_SOCKET_SHUTDOWN_FAILED);
    PyModule_AddIntConstant(m, "MQ_SOCKET_CLOSE_FAILED", MQ_SOCKET_CLOSE_FAILED);
    PyModule_AddIntConstant(m, "MQ_SSL_INIT_ERROR", MQ_SSL_INIT_ERROR);
    PyModule_AddIntConstant(m, "MQ_SSL_SOCKET_INIT_ERROR", MQ_SSL_SOCKET_INIT_ERROR);
    PyModule_AddIntConstant(m, "MQ_SSL_CERT_ERROR", MQ_SSL_CERT_ERROR);
    PyModule_AddIntConstant(m, "MQ_SSL_ERROR", MQ_SSL_ERROR);
    PyModule_AddIntConstant(m, "MQ_SSL_ALREADY_INITIALIZED", MQ_SSL_ALREADY_INITIALIZED);
    PyModule_AddIntConstant(m, "MQ_SSL_NOT_INITIALIZED", MQ_SSL_NOT_INITIALIZED);

    PyModule_AddIntConstant(m, "MQ_MD5_HASH_FAILURE", MQ_MD5_HASH_FAILURE);
    PyModule_AddIntConstant(m, "MQ_BASE64_ENCODE_FAILURE", MQ_BASE64_ENCODE_FAILURE);

    PyModule_AddIntConstant(m, "MQ_BROKER_BAD_REQUEST", MQ_BROKER_BAD_REQUEST);
    PyModule_AddIntConstant(m, "MQ_BROKER_UNAUTHORIZED", MQ_BROKER_UNAUTHORIZED);
    PyModule_AddIntConstant(m, "MQ_BROKER_FORBIDDEN", MQ_BROKER_FORBIDDEN);
    PyModule_AddIntConstant(m, "MQ_BROKER_NOT_FOUND", MQ_BROKER_NOT_FOUND);
    PyModule_AddIntConstant(m, "MQ_BROKER_NOT_ALLOWED", MQ_BROKER_NOT_ALLOWED);
    PyModule_AddIntConstant(m, "MQ_BROKER_TIMEOUT", MQ_BROKER_TIMEOUT);
    PyModule_AddIntConstant(m, "MQ_BROKER_CONFLICT", MQ_BROKER_CONFLICT);
    PyModule_AddIntConstant(m, "MQ_BROKER_GONE", MQ_BROKER_GONE);
    PyModule_AddIntConstant(m, "MQ_BROKER_PRECONDITION_FAILED", MQ_BROKER_PRECONDITION_FAILED);
    PyModule_AddIntConstant(m, "MQ_BROKER_INVALID_LOGIN", MQ_BROKER_INVALID_LOGIN);
    PyModule_AddIntConstant(m, "MQ_BROKER_ERROR", MQ_BROKER_ERROR);
    PyModule_AddIntConstant(m, "MQ_BROKER_NOT_IMPLEMENTED", MQ_BROKER_NOT_IMPLEMENTED);
    PyModule_AddIntConstant(m, "MQ_BROKER_UNAVAILABLE", MQ_BROKER_UNAVAILABLE);
    PyModule_AddIntConstant(m, "MQ_BROKER_BAD_VERSION", MQ_BROKER_BAD_VERSION);
    PyModule_AddIntConstant(m, "MQ_BROKER_RESOURCE_FULL", MQ_BROKER_RESOURCE_FULL);
    PyModule_AddIntConstant(m, "MQ_BROKER_ENTITY_TOO_LARGE", MQ_BROKER_ENTITY_TOO_LARGE);

    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_GOODBYE_FAILED", MQ_PROTOCOL_HANDLER_GOODBYE_FAILED);
    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_START_FAILED", MQ_PROTOCOL_HANDLER_START_FAILED);
    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_STOP_FAILED", MQ_PROTOCOL_HANDLER_STOP_FAILED);
    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_AUTHENTICATE_FAILED", MQ_PROTOCOL_HANDLER_AUTHENTICATE_FAILED);
    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_UNEXPECTED_REPLY", MQ_PROTOCOL_HANDLER_UNEXPECTED_REPLY);
    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_WRITE_ERROR", MQ_PROTOCOL_HANDLER_WRITE_ERROR);
    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_READ_ERROR", MQ_PROTOCOL_HANDLER_READ_ERROR);
    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_ERROR", MQ_PROTOCOL_HANDLER_ERROR);
    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_SET_CLIENTID_FAILED", MQ_PROTOCOL_HANDLER_SET_CLIENTID_FAILED);
    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_DELETE_DESTINATION_FAILED", MQ_PROTOCOL_HANDLER_DELETE_DESTINATION_FAILED);
    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_HELLO_FAILED", MQ_PROTOCOL_HANDLER_HELLO_FAILED);
    PyModule_AddIntConstant(m, "MQ_PROTOCOL_HANDLER_RESUME_FLOW_FAILED", MQ_PROTOCOL_HANDLER_RESUME_FLOW_FAILED);

    PyModule_AddIntConstant(m, "MQ_READ_CHANNEL_DISPATCH_ERROR", MQ_READ_CHANNEL_DISPATCH_ERROR);

    PyModule_AddIntConstant(m, "MQ_READQTABLE_ERROR", MQ_READQTABLE_ERROR);

    PyModule_AddIntConstant(m, "MQ_UNSUPPORTED_ARGUMENT_VALUE", MQ_UNSUPPORTED_ARGUMENT_VALUE);

    PyModule_AddIntConstant(m, "MQ_SESSION_CLOSED", MQ_SESSION_CLOSED);
    PyModule_AddIntConstant(m, "MQ_CONSUMER_NOT_IN_SESSION", MQ_CONSUMER_NOT_IN_SESSION);
    PyModule_AddIntConstant(m, "MQ_PRODUCER_NOT_IN_SESSION", MQ_PRODUCER_NOT_IN_SESSION);
    PyModule_AddIntConstant(m, "MQ_QUEUE_CONSUMER_CANNOT_BE_DURABLE", MQ_QUEUE_CONSUMER_CANNOT_BE_DURABLE);
    PyModule_AddIntConstant(m, "MQ_CANNOT_UNSUBSCRIBE_ACTIVE_CONSUMER", MQ_CANNOT_UNSUBSCRIBE_ACTIVE_CONSUMER);
    PyModule_AddIntConstant(m, "MQ_RECEIVE_QUEUE_CLOSED", MQ_RECEIVE_QUEUE_CLOSED);
    PyModule_AddIntConstant(m, "MQ_RECEIVE_QUEUE_ERROR", MQ_RECEIVE_QUEUE_ERROR);
    PyModule_AddIntConstant(m, "MQ_NO_CONNECTION", MQ_NO_CONNECTION);
    PyModule_AddIntConstant(m, "MQ_CONNECTION_CLOSED", MQ_CONNECTION_CLOSED);
    PyModule_AddIntConstant(m, "MQ_INVALID_ACKNOWLEDGE_MODE", MQ_INVALID_ACKNOWLEDGE_MODE);
    PyModule_AddIntConstant(m, "MQ_INVALID_DESTINATION_TYPE", MQ_INVALID_DESTINATION_TYPE);
    PyModule_AddIntConstant(m, "MQ_INVALID_RECEIVE_MODE", MQ_INVALID_RECEIVE_MODE);
    PyModule_AddIntConstant(m, "MQ_NOT_SYNC_RECEIVE_MODE", MQ_NOT_SYNC_RECEIVE_MODE);
    PyModule_AddIntConstant(m, "MQ_NOT_ASYNC_RECEIVE_MODE", MQ_NOT_ASYNC_RECEIVE_MODE);
    PyModule_AddIntConstant(m, "MQ_TRANSACTED_SESSION", MQ_TRANSACTED_SESSION);
    PyModule_AddIntConstant(m, "MQ_NOT_TRANSACTED_SESSION", MQ_NOT_TRANSACTED_SESSION);
    PyModule_AddIntConstant(m, "MQ_SESSION_NOT_CLIENT_ACK_MODE", MQ_SESSION_NOT_CLIENT_ACK_MODE);
    PyModule_AddIntConstant(m, "MQ_TRANSACTION_ID_IN_USE", MQ_TRANSACTION_ID_IN_USE);
    PyModule_AddIntConstant(m, "MQ_INVALID_TRANSACTION_ID", MQ_INVALID_TRANSACTION_ID);
    PyModule_AddIntConstant(m, "MQ_THREAD_OUTSIDE_XA_TRANSACTION", MQ_THREAD_OUTSIDE_XA_TRANSACTION);
    PyModule_AddIntConstant(m, "MQ_XA_SESSION_NO_TRANSATION", MQ_XA_SESSION_NO_TRANSATION);
    PyModule_AddIntConstant(m, "MQ_XA_SESSION_IN_PROGRESS", MQ_XA_SESSION_IN_PROGRESS);

    PyModule_AddIntConstant(m, "MQ_MESSAGE_NO_DESTINATION", MQ_MESSAGE_NO_DESTINATION);
    PyModule_AddIntConstant(m, "MQ_DESTINATION_NO_CLASS", MQ_DESTINATION_NO_CLASS);
    PyModule_AddIntConstant(m, "MQ_DESTINATION_NO_NAME", MQ_DESTINATION_NO_NAME);
    PyModule_AddIntConstant(m, "MQ_NO_REPLY_TO_DESTINATION", MQ_NO_REPLY_TO_DESTINATION);

    PyModule_AddIntConstant(m, "MQ_PRODUCER_NO_DESTINATION", MQ_PRODUCER_NO_DESTINATION);
    PyModule_AddIntConstant(m, "MQ_PRODUCER_HAS_DESTINATION", MQ_PRODUCER_HAS_DESTINATION);
    PyModule_AddIntConstant(m, "MQ_INVALID_DELIVERY_MODE", MQ_INVALID_DELIVERY_MODE);
    PyModule_AddIntConstant(m, "MQ_INVALID_PRIORITY", MQ_INVALID_PRIORITY);
    PyModule_AddIntConstant(m, "MQ_PRODUCER_CLOSED", MQ_PRODUCER_CLOSED);
    PyModule_AddIntConstant(m, "MQ_SEND_NOT_FOUND", MQ_SEND_NOT_FOUND);
    PyModule_AddIntConstant(m, "MQ_SEND_TOO_LARGE", MQ_SEND_TOO_LARGE);
    PyModule_AddIntConstant(m, "MQ_SEND_RESOURCE_FULL", MQ_SEND_RESOURCE_FULL);

    PyModule_AddIntConstant(m, "MQ_CONSUMER_NO_DURABLE_NAME", MQ_CONSUMER_NO_DURABLE_NAME);
    PyModule_AddIntConstant(m, "MQ_CONSUMER_NOT_INITIALIZED", MQ_CONSUMER_NOT_INITIALIZED);
    PyModule_AddIntConstant(m, "MQ_CONSUMER_EXCEPTION", MQ_CONSUMER_EXCEPTION);
    PyModule_AddIntConstant(m, "MQ_CONSUMER_NO_SESSION", MQ_CONSUMER_NO_SESSION);
    PyModule_AddIntConstant(m, "MQ_MESSAGE_NOT_IN_SESSION", MQ_MESSAGE_NOT_IN_SESSION);
    PyModule_AddIntConstant(m, "MQ_NO_MESSAGE", MQ_NO_MESSAGE);
    PyModule_AddIntConstant(m, "MQ_CONSUMER_CLOSED", MQ_CONSUMER_CLOSED);
    PyModule_AddIntConstant(m, "MQ_INVALID_MESSAGE_SELECTOR", MQ_INVALID_MESSAGE_SELECTOR);
    PyModule_AddIntConstant(m, "MQ_CONSUMER_NOT_FOUND", MQ_CONSUMER_NOT_FOUND);
    PyModule_AddIntConstant(m, "MQ_DESTINATION_CONSUMER_LIMIT_EXCEEDED", MQ_DESTINATION_CONSUMER_LIMIT_EXCEEDED);
    PyModule_AddIntConstant(m, "MQ_CONSUMER_DESTINATION_NOT_FOUND", MQ_CONSUMER_DESTINATION_NOT_FOUND);

    PyModule_AddIntConstant(m, "MQ_CONNECTION_START_ERROR", MQ_CONNECTION_START_ERROR);
    PyModule_AddIntConstant(m, "MQ_CONNECTION_CREATE_SESSION_ERROR", MQ_CONNECTION_CREATE_SESSION_ERROR);
    PyModule_AddIntConstant(m, "MQ_CONNECTION_OPEN_ERROR", MQ_CONNECTION_OPEN_ERROR);
    PyModule_AddIntConstant(m, "MQ_CONNECTION_UNSUPPORTED_TRANSPORT", MQ_CONNECTION_UNSUPPORTED_TRANSPORT);

    PyModule_AddIntConstant(m, "MQ_HANDLED_OBJECT_INVALID_HANDLE_ERROR", MQ_HANDLED_OBJECT_INVALID_HANDLE_ERROR);
    PyModule_AddIntConstant(m, "MQ_HANDLED_OBJECT_IN_USE", MQ_HANDLED_OBJECT_IN_USE);
    PyModule_AddIntConstant(m, "MQ_HANDLED_OBJECT_NO_MORE_HANDLES", MQ_HANDLED_OBJECT_NO_MORE_HANDLES);

    PyModule_AddIntConstant(m, "MQ_REFERENCED_FREED_OBJECT_ERROR", MQ_REFERENCED_FREED_OBJECT_ERROR);

    PyModule_AddIntConstant(m, "MQ_DESTINATION_NOT_TEMPORARY", MQ_DESTINATION_NOT_TEMPORARY);
    PyModule_AddIntConstant(m, "MQ_TEMPORARY_DESTINATION_NOT_IN_CONNECTION", MQ_TEMPORARY_DESTINATION_NOT_IN_CONNECTION);

    PyModule_AddIntConstant(m, "MQ_CALLBACK_RUNTIME_ERROR", MQ_CALLBACK_RUNTIME_ERROR);

    PyModule_AddIntConstant(m, "MQ_STATUS_INVALID_HANDLE", MQ_STATUS_INVALID_HANDLE);
    PyModule_AddIntConstant(m, "MQ_NO_MESSAGE_PROPERTIES", MQ_NO_MESSAGE_PROPERTIES);
    PyModule_AddIntConstant(m, "MQ_STATUS_NULL_LOGGER", MQ_STATUS_NULL_LOGGER);
    PyModule_AddIntConstant(m, "MQ_STATUS_CONNECTION_NOT_CLOSED", MQ_STATUS_CONNECTION_NOT_CLOSED);
    PyModule_AddIntConstant(m, "MQ_NOT_XA_CONNECTION", MQ_NOT_XA_CONNECTION);
    PyModule_AddIntConstant(m, "MQ_ILLEGAL_CLOSE_XA_CONNECTION", MQ_ILLEGAL_CLOSE_XA_CONNECTION);
}
